﻿#pragma once

#include "service_finder/service_finder.hh"
#ifndef DISABLE_SB_CODE
#include "util/object_pool.hh"
#endif
#include <ctime>
#include <memory>
#include <random>
#include <string>
#include <unordered_map>

namespace kratos {
namespace service {

class ZookeeperClient;

class ServiceFinderZookeeper : public ServiceFinder {
  using ListenerMap = std::unordered_map<std::string, ServiceChange>;
#ifndef DISABLE_SB_CODE
  unique_pool_ptr<ZookeeperClient> zoo_ptr_; ///< Zookeeper实例
#else
  std::unique_ptr<ZookeeperClient> zoo_ptr_; ///< Zookeeper实例
#endif
  std::mt19937 range_;       ///< 随机数
  std::time_t last_tick_{0}; ///< 上一次update的时间戳，毫秒
  constexpr static std::time_t CHECK_INTERVAL = 5000; ///< 断线检测周期，毫秒
  ListenerMap listener_map_;                          ///< 监听器表
  std::string version_;                               ///< 版本号

public:
  ServiceFinderZookeeper();
  virtual ~ServiceFinderZookeeper();
  virtual auto start(const std::string &servers, int timeout,
                     const std::string &version) -> bool override;
  virtual auto stop() -> void override;
  virtual void update(std::time_t tick) override;
  virtual auto find_service(const std::string &name,
                            std::list<std::string> &hosts) -> bool override;
  virtual auto find_service(const std::string &name, std::string &host)
      -> bool override;
  virtual auto dump(std::ostream &ostream) -> void override;
  virtual auto remove_cache(const std::string &name, const std::string &host)
      -> void override;
  virtual auto get_service_host_count(const std::string &name)
      -> std::size_t override;
  virtual auto add_listener(const std::string &listener_name,
                            ServiceChange service_change) -> bool override;
};

} // namespace service
} // namespace kratos
